package com.tju.resource.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tju.resource.common.ServiceException;
import com.tju.resource.mapper.*;
import com.tju.resource.model.*;
import com.tju.resource.server.TbCommandService;
import com.tju.resource.server.TbOrderService;
import com.tju.resource.server.TbProdPlanService;
import com.tju.resource.tool.result.Result;
import com.tju.resource.tool.result.ResultEnum;
import com.tju.resource.tool.result.ResultUtil;
import com.tju.resource.tool.tool.ChineseExceptionUtils;
import com.tju.resource.tool.tool.ClientParameters;
import com.tju.resource.tool.tool.EmptyUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 */
@Service
@Slf4j
public class TbOrderServiceImpl implements TbOrderService {
    //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @Autowired
    private TbProdPlanService pService;
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private ChineseExceptionUtils zh_CH;
    //@Autowired
    //private SysParamsService paramsServiceService;
    @Autowired
    private TbCommandService tbCommandService;
    @Autowired
    private TbCustomerMapper tbCustomerMapper;
    @Autowired
    private TbMaterialMapper tbMaterialMapper;
    @Autowired
    private TbOrdMatlMapper tbOrdMatlMapper;
    @Autowired
    private TbSharperMapper tbSharperMapper;

    /**
     * 根据订单id查询物料
     *
     * @return
     */
    public List<TbOrdMatl> listTbOrdMatlByoId(Long oid) {
        QueryWrapper<TbOrdMatl> qw = new QueryWrapper<>();
        qw.eq("oid", oid);
        return tbOrdMatlMapper.selectList(qw);
    }

    /**
     * 查询订单
     *
     * @return 订单列表
     */
    @Override
    public Result<Object> selectTbOrderList(Map<String, String> pa) {
        try {
            int pageNum = Integer.parseInt(pa.get("page"));  //页码
            int limit = Integer.parseInt(pa.get("limit"));
            if (EmptyUtils.isNotEmpty(pageNum) && EmptyUtils.isNotEmpty(limit)) { //不等于空
                pageNum = pageNum == 0 ? 1 : pageNum;
                limit = limit == 0 ? 10 : limit;
                Page<TbOrder> page = new Page<>(pageNum, limit);
                IPage<TbOrder> iPage = tbOrderMapper.selectTbOrderList(page, pa);
                List<TbOrder> orderList = new CopyOnWriteArrayList<>(iPage.getRecords());
                for (TbOrder order : orderList) {
                    //if (EmptyUtils.isNotEmpty(tbCommandService.getByOrderId(order.getId())))  //判断指令是否使用
                    //order.setDisabled(true); //使用为true
                    List<TbOrdMatl> listOrdMatl = tbOrderMapper.getListMaterial(order.getId(), pa.get("matlNumber"));//根据订单id和物料号查询
                    if (EmptyUtils.isEmpty(listOrdMatl)) {  //判断没有物料就删除当前订单
                        orderList.remove(order); //删除
                        continue;//直接下一个循环
                    }
                    order.setListOrdMatl(listOrdMatl);
                    for (TbOrdMatl tbOrdMatl : listOrdMatl) {
                        if (EmptyUtils.isNotEmpty(tbOrderMapper.orderByIdANDMatlId(tbOrdMatl.getOid(), tbOrdMatl.getMatiId()))) //判断被选中
                            tbOrdMatl.setSelected(true); //选中
                    }

                    if (StringUtils.equals(pa.get("approve") + "", "1")) {
                        if (order.getCheckOrder().equals(1L)) {
                            if (!order.getApprove().equals(1L)) {
                                orderList.remove(order);
                            }
                        }
                    }
                }
//                Long[] matiId;
//                for (TbOrder o :iPage.getRecords() ) {
//                    List<TbOrdMatl> tbOrdMatls = listTbOrdMatlByoId(o.getId());
//                    matiId = new Long[tbOrdMatls.size()];
//                    for (int tbOrdMatlsIndex = 0; tbOrdMatlsIndex < tbOrdMatls.size(); tbOrdMatlsIndex++) { //循环生产计划
//                        matiId[tbOrdMatlsIndex] = tbOrdMatls.get(tbOrdMatlsIndex).getMatiId();  //拿到生产计划id
//                    }
//                    o.setMatlId(matiId);
//                }

//                for (TbOrder order : iPage.getRecords()) {  //循环订单号
//                    order.setPlanNumber(pService.getProds(order.getId())); //用订单号算出生产计划数量
//                }
                return ResultUtil.success(ResultEnum.SUCCESS, orderList, iPage.getTotal());
            } else {
                ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 添加订单
     *
     * @param order 订单信息
     * @return
     */
    @Override
    @Transactional
    public Result<Object> insertTbOrder(TbOrder order) {
        //int customerIndex = 0; //模型
        String orderNumber = order.getOrderNumber(); //订单号
        if (EmptyUtils.isNotEmpty(checkOrderNumberUnique(orderNumber))) {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单号重复了：" + orderNumber);
        }
            /*if (tbOrderMapper.selectExistByClientName(order).size() > 0) { //如果被使用过就不被用
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "该型号:" + order.getCustomer() + "其他客户已用！");
            }
            long data = (order.getDelivery().getTime() - sdf.parse(sdf.format(new Date())).getTime()) / (24 * 3600 * 1000);
            long paramsValue = Long.parseLong(paramsServiceService.get("OD_DELIVERY").getParamsValue());
            if (data < paramsValue) {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "交期时间必须大于订单时间" + paramsValue + "天");
            }*/
        String customer = order.getCustomer();  //型号
/*            String clientName = order.getClientName(); //客户名称
            TbClient tbClient = existClientName(clientName);//查询客户是否存在
            if (EmptyUtils.isEmpty(tbClient)) {
                tbClient = nonentityClient(clientName, order.getCreateBy());  //添加型号
            }*/
        TbCustomer tbCustomer = existCustomer(customer); //查询型号是否存在
        if (EmptyUtils.isEmpty(tbCustomer)) {
            tbCustomer = nonentityCustomer(customer);  //添加型号
        }
        order.setClientId(order.getClientId()); //客户id
        order.setCustomerId(tbCustomer.getId()); //客户型号id
        if (tbOrderMapper.insert(order) > 0) {
            addTbOrdMatl(order); //添加物料关联表
            return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.AddedSuccessfully);
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.AddFailed);
    }

    /**
     * 修改订单
     *
     * @param order
     * @return
     */
    @Override
    @Transactional
    public Result<Object> updateTbOrder(TbOrder order) {
        TbOrder tbOrder = tbOrderMapper.selectById(order.getId());
        if (EmptyUtils.isEmpty(tbOrder)) {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "不存在该订单！");
        }
        if (!tbOrder.getOrderNumber().equals(order.getOrderNumber())) {
            if (EmptyUtils.isNotEmpty(checkOrderNumberUnique(order.getOrderNumber()))) {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单号重复了：" + order.getOrderNumber());
            }
        }
        String customer = order.getCustomer();  //型号
        TbCustomer tbCustomer = existCustomer(customer); //查询型号是否存在
        if (EmptyUtils.isEmpty(tbCustomer)) {
            tbCustomer = nonentityCustomer(customer);  //添加型号
        }
//            if (order.getOrderPcs() < order.getPlanNumber()) {
//                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单数不能小于计划数!");
//            }
        order.setClientId(order.getClientId()); //客户id
        order.setCustomerId(tbCustomer.getId()); //客户型号id
        //Long prods = pService.getProds(order.getId());
        // prods = prods == null ? 0L : prods;
//            if (order.getOrderPcs() >= prods) {
//                order.setUpdateTime(new Date());
//                if (tbOrderMapper.updateById(order) > 0) {
//                    return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyModified);
//                }
//            } else {
//                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单数不能小于计划数!");
//            }
        if (tbOrderMapper.updateById(order) > 0) { //修改成功
            deleteTbOrdMatl(order.getId());//删除之前的关联表
            addTbOrdMatl(order);//添加物料关联表
            return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyModified);
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailToEdit);
    }

    /**
     * 删除订单
     *
     * @param order
     * @return
     */
    @Override
    @Transactional
    public Result<Object> deleteTbOrder(TbOrder order) {
        try {
            if (EmptyUtils.isNotEmpty(order.getId())) {
                if (pService.getByOR(order.getId()).size() != 0) {//根据订单号查询是否存在生产计划
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, "当前订单下存在生产计划，不允许删除！");
                } else if (tbCommandService.getByOrderId(order.getId()).size() != 0) {//根据订单号查询是否存在指令号
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, "当前订单下存在指令号，不允许删除！");
                }
                if (tbOrderMapper.selectById(order.getId()).getOrderState() == 1L) {
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, "该订单已完成不能删除！");
                }
                deleteTbOrdMatl(order.getId());//删除关联的订单表
                //不存在就删除
                if (tbOrderMapper.deleteById(order.getId()) > 0) {
                    return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyDeleted);
                }
            } else {
                ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailedToDelete);
    }

    /**
     * 导出订单
     *
     * @return
     */
    @Override
    public Result<Object> exportOrder(ClientParameters parameter) {
        try {
            String one = parameter.getOne(); //订单号
            String two = parameter.getTwo(); //指令号
            String ugc = parameter.getUgc(); //客户名称
            String beginDate = parameter.getBeginDate(); //交期时间
            String finishDate = parameter.getFinishDate(); //交期时间
            if (EmptyUtils.isEmpty(one) && EmptyUtils.isEmpty(two) && EmptyUtils.isEmpty(ugc) && EmptyUtils.isEmpty(beginDate) && EmptyUtils.isEmpty(finishDate)) {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
            }
            List<TbOrder> tbOrders = tbOrderMapper.selectList(QueryWrapperOrder(parameter));
            if (tbOrders.size() != 0) {
                return ResultUtil.success(ResultEnum.SUCCESS, tbOrders);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "导出失败,无数据!");
    }

    /**
     * 导出订单
     *
     * @return
     */
    @Override
    public Result<Object> importOrder(File file) {
        return null;
    }

    /**
     * 判断唯一的订单
     *
     * @param
     * @return
     */
    public TbOrder checkOrderNumberUnique(String orderNumber) {
        QueryWrapper<TbOrder> qw = new QueryWrapper<>();
        qw.eq("order_number", orderNumber);
        return tbOrderMapper.selectOne(qw);
    }

    /**
     * 删除物料跟订单关联表
     */
    private void deleteTbOrdMatl(Long id) {
        List<TbOrdMatl> tbOrdMatls = listTbOrdMatlByoId(id);
        for (TbOrdMatl tbOrdMatl : tbOrdMatls) {
            TbMaterial material = tbMaterialMapper.selectByMatilId(tbOrdMatl.getMatiId());//查询物料
            Long withholdingLife = (material.getWithholdingLife() == null ? 0 : material.getWithholdingLife()) - tbOrdMatl.getOrderPcs();//代扣
            updateSharper(material.getSid(), null, withholdingLife < 0 ? 0 : withholdingLife); //修改缓存
            tbOrdMatlMapper.deleteById(tbOrdMatl.getCorrelationId());
        }
    }

    /**
     * 订单查询条件
     *
     * @param parameter 参数
     * @return
     */
    public QueryWrapper<TbOrder> QueryWrapperOrder(ClientParameters parameter) {
        QueryWrapper<TbOrder> qw = new QueryWrapper<>();
        String one = parameter.getOne(); //订单号
        String two = parameter.getTwo(); //指令号
        String ugc = parameter.getUgc(); //客户名称
        String beginDate = parameter.getBeginDate(); //交期时间
        String finishDate = parameter.getFinishDate(); //交期时间
        if (EmptyUtils.isNotEmpty(one)) {
            qw.like("order_number", one);
        }
        if (EmptyUtils.isNotEmpty(two)) {
            qw.like("command_number", two);
        }
        if (EmptyUtils.isNotEmpty(ugc)) {
            qw.like("client_name", ugc);
        }
        if (EmptyUtils.isNotEmpty(beginDate) && EmptyUtils.isNotEmpty(finishDate)) {
            qw.between("delivery", beginDate, finishDate);
        }
        qw.orderByDesc("id");
        return qw;
    }

    /**
     * 根据客户名查询型号
     */
    @Override
    public Result<Object> selectTbCustomerByCustomer(TbOrder order) {
        return ResultUtil.success(ResultEnum.SUCCESS, tbOrderMapper.selectTbCustomerByCustomer(order));
    }

    /**
     * 查询客户名称
     */
    @Override
    public Result<Object> selectByClientName(TbOrder tbOrder) {
        return ResultUtil.success(ResultEnum.SUCCESS, tbOrderMapper.selectByClientName(tbOrder));
    }

    /**
     * 查询客户型号是否被其他客户用
     */
    @Override
    public Result<Object> selectExistByClientName(TbOrder tbOrder) {
        if (tbOrderMapper.selectExistByClientName(tbOrder).size() > 0) {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "该型号:" + tbOrder.getCustomer() + "已被其他客户使用");
        } else {
            return ResultUtil.success(ResultEnum.SUCCESS, "该型号:" + tbOrder.getCustomer() + "可以使用");
        }

    }

    /**
     * 修改该订单为审核通过
     *
     * @param tbOrder
     * @return
     */
    @Override
    @Transactional
    public Result<Object> updateApprove(TbOrder tbOrder) {
        try {
            if (EmptyUtils.isNotEmpty(tbOrder.getId())) {
                if (tbOrderMapper.updateById(tbOrder) > 0) {
                    return ResultUtil.success(ResultEnum.SUCCESS, "审核完成!");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ResultUtil.error(ResultEnum.SUCCESS, "审核失败");
    }

    /**
     * 查询是否存在型号
     */
    public TbCustomer existCustomer(String customer) {
        QueryWrapper<TbCustomer> qw = new QueryWrapper<>();
        qw.eq("customer", customer);
        return tbCustomerMapper.selectOne(qw);
    }

    /**
     * 不存在型号就添加
     */
    public TbCustomer nonentityCustomer(String customer) {
        TbCustomer tbCustomer = new TbCustomer();
        tbCustomer.setCustomer(customer);
        tbCustomerMapper.insert(tbCustomer);
        return tbCustomer;
    }

    /**
     * 添加物料关联表
     *
     * @param order
     */
    public void addTbOrdMatl(TbOrder order) {
        if (EmptyUtils.isNotEmpty(order.getListOrdMatl())) {
            List<TbOrdMatl> listOrdMatl = order.getListOrdMatl(); //物料对象
            long planNumber = 0L; //计划数
            for (TbOrdMatl tbOrdMatl : listOrdMatl) { //循环
                Long orderPcs = tbOrdMatl.getOrderPcs();  //订单数
                if (EmptyUtils.isEmpty(orderPcs) || orderPcs == 0L) {
                    throw new ServiceException("订单数量不能为空!");
                }
                if (EmptyUtils.isEmpty(tbOrdMatl.getDelivery())) {
                    throw new ServiceException("交期不能为空!");
                }
                long id = tbOrdMatl.getId();
                TbMaterial material = tbMaterialMapper.selectByMatilId(id);
                if (EmptyUtils.isEmpty(material)) {
                    throw new ServiceException("没有该物料!");
                }
                long sid = material.getSid(); //模具id
                long residualLife = material.getResidualLife(); //剩余寿命
                long withholdingLife = material.getWithholdingLife() + orderPcs;//缓存寿命
                if ((withholdingLife) > residualLife) //缓存寿命+订单数不能大于剩下寿命
                    throw new ServiceException("剩下寿命不足!");
                updateSharper(sid, null, withholdingLife); //修改缓存寿命
                long fpPcs = EmptyUtils.isEmpty(material.getFpPcs()) ? 0L : material.getFpPcs(); //成品数量
                double wdWeight = EmptyUtils.isEmpty(material.getWdWeight()) ? 0 : material.getWdWeight();//水口重量
                double matlWeight = EmptyUtils.isEmpty(material.getMatlWeight()) ? 0 : material.getMatlWeight();//物料单重
                tbOrdMatl.setNeedWeight(orderPcs <= fpPcs ? 0.0 : (matlWeight + wdWeight) * orderPcs - fpPcs); //判断订单数小于成品需要数为0.0否者就水口重量+物料单重乘订单-成品数量
                tbOrdMatl.setLackPcs(orderPcs <= fpPcs ? 0 : orderPcs - fpPcs); //判断订单数小于成品需要数为0
                tbOrdMatl.setWeight((matlWeight + wdWeight) * orderPcs); //所有重量
                tbOrdMatl.setOid(order.getId()); //订单id
                tbOrdMatl.setMatiId(id);//物料id
                tbOrdMatlMapper.insert(tbOrdMatl);
                planNumber += orderPcs;
            }
            order.setPlanNumber(planNumber);
            tbOrderMapper.updateById(order);//修改计划数
        } else {
            throw new ServiceException("没选择物料!");
        }
    }
    /**
     * 不存在客户就添加
     */
    /*public TbClient nonentityClient(String clientName) {
        TbClient tbClient = new TbClient();
        tbClient.setClientName(clientName);
        tbClientMapper.insert(tbClient);
        return tbClient;
    }*/

    /**
     * 新增订单同一个客户选着上一次完成的自动把上一次的生产计划添加到这个订单下
     */
    /*public int insertPlan(Long customerId, Long orderId) {
        int result = 0;
        QueryWrapper<TbOrder> qw = new QueryWrapper<>();
        qw.eq("customer_id", customerId);
        qw.eq("order_state", 1);
        qw.orderByAsc("id");
        List<TbOrder> tbOrders = tbOrderMapper.selectList(qw); //查询这个型号
        if (tbOrders.size() > 0) {
            List<TbProdPlan> byOR = pService.getByOR(tbOrders.get(0).getId()); //这个型号为完成把他下面的生产计划复制到这个订单下面
            for (TbProdPlan tbProdPlan : byOR) {
                tbProdPlan.setOrderId(orderId); //修改到这个订单
                result = tbProdPlanMapper.insert(tbProdPlan);
            }
        }
        return result;
    }*/

    /**
     * 根据订单号跟物料号修改重量缺少数量
     */
    public boolean updateOrdMatl(String orderNumber, String matlNumber) {
        if (EmptyUtils.isEmpty(orderNumber) && EmptyUtils.isEmpty(matlNumber)) {
            throw new ServiceException("订单号跟物料编号不能为空");
        }
        QueryWrapper<TbOrder> qwOrder = new QueryWrapper<>();  //查询
        qwOrder.eq("order_number", orderNumber);//根据订单号查询订单
        TbOrder tbOrder = tbOrderMapper.selectOne(qwOrder); //订单对象
        QueryWrapper<TbMaterial> qwMatl = new QueryWrapper<>();  //查询
        qwMatl.eq("matl_number", matlNumber);//根据物料编码查询
        TbMaterial material = tbMaterialMapper.selectOne(qwMatl);//物料对象

        QueryWrapper<TbOrdMatl> qwOrd = new QueryWrapper<>();//订单跟物料的关联表
        qwOrd.eq("oid", tbOrder.getId()); //根据订单id
        qwOrd.eq("mati_id", material.getId());//根据物料id
        TbOrdMatl tbOrdMatl = tbOrdMatlMapper.selectOne(qwOrd);//关联对象
        Long orderPcs = tbOrdMatl.getOrderPcs();  //订单数
        long finishQuantity = tbOrdMatl.getFinishQuantity() == null ? 0 : tbOrdMatl.getFinishQuantity();  //完成数量
        long fpPcs = EmptyUtils.isEmpty(material.getFpPcs()) ? 0L : material.getFpPcs(); //成品数量
        double wdWeight = EmptyUtils.isEmpty(material.getWdWeight()) ? 0 : material.getWdWeight();//水口重量
        double matlWeight = EmptyUtils.isEmpty(material.getMatlWeight()) ? 0 : material.getMatlWeight();//物料单重
        double needWeight = (matlWeight + wdWeight) * (orderPcs - fpPcs - finishQuantity);  //缺少重量
        tbOrdMatl.setNeedWeight(orderPcs <= fpPcs ? 0.0 : needWeight < 0 ? 0 : needWeight); //判断订单数小于成品需要数为0.0否者就水口重量+物料单重乘订单-成品数量
        long lackPcs = orderPcs - fpPcs - finishQuantity;  //订单缺少数量
        tbOrdMatl.setLackPcs(orderPcs <= fpPcs ? 0 : lackPcs < 0 ? 0 : lackPcs); //判断订单数小于成品需要数为0
        tbOrdMatl.setWeight((matlWeight + wdWeight) * orderPcs); //所有重量
        long unFinishQuantity = orderPcs - finishQuantity;//未完成数量
        tbOrdMatl.setUnFinishQuantity(unFinishQuantity < 0 ? 0 : unFinishQuantity);  //未完成数量
        tbOrdMatl.setOid(tbOrder.getId()); //订单id
        tbOrdMatl.setMatiId(material.getId());//物料id
        return tbOrdMatlMapper.updateById(tbOrdMatl) > 0;
    }

    /**
     * 模具修改缓存数量
     */
    public void updateSharper(Long id, Long residualLife, Long withholdingLife) {
        TbSharper sharper = new TbSharper(); //模具对象
        sharper.setId(id);//模具id
        if (EmptyUtils.isNotEmpty(residualLife)) sharper.setResidualLife(residualLife); //剩余寿命
        sharper.setWithholdingLife(withholdingLife);//缓存寿命
        tbSharperMapper.updateById(sharper);//修改
    }
}




